#ifndef _RTP_H_
#define _RTP_H_

#include <cstdint>
#include <cstdlib>
#include <cassert>
#include <netinet/in.h>

#define RTP_VERSION             2

#define CLOCK_FPS               90000
#define RTP_PAYLOAD_TYPE_MP2T   33
#define RTP_PAYLOAD_TYPE_FLV    77
#define RTP_PAYLOAD_TYPE_H264   96
#define RTP_PAYLOAD_TYPE_AAC    97

#define RTP_HEADER_SIZE         12
#define RTP_MAX_PKT_SIZE        1500-20-8

struct RtpHeader
{
    /* byte 0 */
    uint8_t csrcLen: 4;
    uint8_t extension: 1;
    uint8_t padding: 1;
    uint8_t version: 2;

    /* byte 1 */
    uint8_t payloadType: 7;
    uint8_t marker: 1;
    
    /* bytes 2,3 */
    uint16_t seq;
    
    /* bytes 4-7 */
    uint32_t timestamp;
    
    /* bytes 8-11 */
    uint32_t ssrc;
};

class RtpPacket
{
public:
    RtpPacket() : 
        mBuffer(new uint8_t[RTP_MAX_PKT_SIZE + RTP_HEADER_SIZE]),
        mRtpHeader(new RtpHeader()),
        mSize(0)
    {
        // 如果成员变量中有 a non static const member，就不能再括号里面初始化
        // 在里面初始化叫做 member assignment，在外面叫做 member initialization
        // mBuffer = mRtpHeader + payload
    }

    ~RtpPacket()
    {
        delete mBuffer;
        delete mRtpHeader;
    }

    void rtpHeaderInit(uint8_t csrcLen, uint8_t extension, uint8_t padding, uint8_t version, 
                    uint8_t payloadType, uint8_t marker,
                    uint16_t seq, uint32_t timestamp, 
                    uint32_t ssrc)
    {
        mRtpHeader->csrcLen = csrcLen;
        mRtpHeader->extension = extension;
        mRtpHeader->padding = padding;
        mRtpHeader->version = version;

        mRtpHeader->payloadType = payloadType;
        mRtpHeader->marker = marker;

        mRtpHeader->seq = seq;
        mRtpHeader->timestamp = timestamp;

        mRtpHeader->ssrc = ssrc;
    }

    uint8_t* mBuffer;
    RtpHeader* mRtpHeader;
    uint8_t payload[0];
    int mSize;  // sizeof(mBuffer)
};

#endif //_RTP_H_